<template>
    <div ref="canvasContainer" style="width: 400px;height: 400px;"></div>
</template>

<script setup>
import { onMounted, ref } from 'vue';
import * as THREE from 'three';
// GLTFLoader：模型加载器用于处理 gltf/glb 格式文件
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const canvasContainer = ref(null);
let carModel = null;

function init() {
    /**
     * 1. 创建3D场景对象Scene
      */
    const scene = new THREE.Scene();
    /**
    * 添加光源
    */
    // 环境光：均匀照亮场景中所有物体，防止全黑
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    scene.add(ambientLight);

    // 平行光：模拟太阳光，给模型带来立体感
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
    directionalLight.position.set(1, 1, 1); // 设置光源位置
    scene.add(directionalLight);
    // 长方体
    // const geometry = new THREE.BoxGeometry(100, 100, 100);
    // const material = new THREE.MeshBasicMaterial({
    //     color: 0xff0000,//0xff0000设置材质颜色为红色
    // });
    // const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
    // //设置网格模型在三维空间中的位置坐标，默认是坐标原点
    // mesh.position.set(0, 0, 0);
    // scene.add(mesh);

    /**
    * 把我的模型加载出来
    */
    const loader = new GLTFLoader();
    loader.load(
        '/models/phone.glb',
        (gltf) => {
            console.log('模型加载成功');
            carModel = gltf.scene;

            const box = new THREE.Box3().setFromObject(carModel);//围绕盒子计算中心点
            const center = new THREE.Vector3(); // 创建一个用来存储尺寸信息的向量 (x, y, z)
            const size = new THREE.Vector3();
            // 获取边界盒的中心点
            box.getCenter(center); // center为中心点
            box.getSize(size);
            // carModel.position.sub(center);
            const maxDim = Math.max(size.x, size.y, size.z);
            const scale = 200 / maxDim;
            carModel.scale.setScalar(scale);
            const modelDepth = size.z * scale;
            console.log(modelDepth);

            carModel.position.set(0, -modelDepth / 2, 0);


            // 通常加载的模型大小或位置不合适，可以手动调整
            // carModel.scale.set(40, 40, 40); // 缩小到一半
            scene.add(carModel);
        },
        (xhr) => {
            console.log((xhr.loaded / xhr.total * 100) + '% loaded');
        }, // 加载失败时的回调函数
        (err) => {
            console.error('模型加载出错了！', err);
        }
    );

    /**
     * 2. 创建一个camera相机
     */
    // width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
    // 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000：远裁截面
    const width = canvasContainer.value.clientWidth; // 400
    const height = canvasContainer.value.clientHeight; // 400
    const camera = new THREE.PerspectiveCamera(45, width / height, 5, 3000);//示例化一个相机
    //相机在Three.js三维坐标系中的位置

    camera.position.set(0, 0, 300); // 相机位置
    camera.lookAt(0, 0, 0);//看向的位置

    /**
    * 坐标显示
    */
    // AxesHelper：辅助观察的坐标系
    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);

    /**
     * 3. webGL渲染器（画笔）
     */
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)
    canvasContainer.value.appendChild(renderer.domElement);

    // renderer.render(scene, camera); //执行渲染操作

    function animate() {
        requestAnimationFrame(animate); // 浏览器会在下一次重绘之前调用这个函数
        // 如果 carModel 存在，就让它绕 Y 轴旋转
        if (carModel) {
            carModel.rotation.y += 0.01; //  恢复旋转逻辑
        }
        renderer.render(scene, camera); // 每一帧都重新渲染
    }
    animate();




}

onMounted(() => {
    init();
})


</script>